package com.pug.security.service.security;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pug.security.mapper.SysLoginUserMapper;
import com.pug.security.pojo.SysLoginUser;
import com.pug.security.pojo.SysPermission;
import com.pug.security.pojo.SysRole;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@Slf4j
public class LoginUserServiceImpl extends ServiceImpl<SysLoginUserMapper, SysLoginUser> implements UserDetailsService, ILoginUserService {

    @Autowired
    private SysLoginUserMapper loginUserMapper;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 1、设定查询条件
        LambdaQueryWrapper<SysLoginUser> queryWrapper = new LambdaQueryWrapper<>();
        // 2、设置数据库的用户名和输入的用户名进行匹配
        queryWrapper.eq(SysLoginUser::getUsername, username);
        // 3、执行查询
        SysLoginUser sysLoginUser = this.getOne(queryWrapper);
        // 4、如果你查询的用户不为空
        if (sysLoginUser != null) {
            // 5:根据用户查询对应的角色
            List<SysRole> roleList = this.loginUserMapper.findSysRoleByUserId(sysLoginUser.getId());
            // TODO 一定要注意：这里的前缀 , 不要在数据库中去加前缀(不灵活)
            // 6:组装用户角色数据
            Set<SimpleGrantedAuthority> roleAuthoritys = roleList.stream().map(role -> "ROLE_" + role.getName())
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toSet());
            // 7:根据用户查询对应的权限
            List<SysPermission> permissionList = this.loginUserMapper.findByAdminUserId(sysLoginUser.getId());
            // 8:组装角色权限数据
            // todo 这里是权限名称(你也可以权限+URL也行（concat拼接)
            Set<SimpleGrantedAuthority> permissionAuthoritys = permissionList.stream().map(permission -> permission.getName())
                    .map(SimpleGrantedAuthority::new)
                    .collect(Collectors.toSet());
            // 9:组合，赋值给User对象
            Set<GrantedAuthority> authorities = new HashSet<>(roleList.size() + permissionAuthoritys.size());
            authorities.addAll(roleAuthoritys);
            authorities.addAll(permissionAuthoritys);
            // 10、把用户查询到的账号和密码，以及角色和权限 赋值给SpringSecurity的UserDetails的自定义的实现者LoginUser
            LoginUser loginUser = new LoginUser(sysLoginUser, roleList.stream().collect(Collectors.toSet()), permissionList.stream().collect(Collectors.toSet()), authorities);
            // 11、设置基本信息
            loginUser.setOs("windows10");
            loginUser.setIp("127.0.0.1");
            loginUser.setIpLocation("陕西西安");
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式
            loginUser.setCurrentTime(df.format(new Date()));
            // 12、返回即可
            return loginUser;
        } else {
            throw new UsernameNotFoundException("用户名或者密码输入有误!!!");
        }

    }


}
